import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Scanner;



public class Main {

    /**
     * @param args
     */
    static boolean continu = true;
    static Scanner sc = new Scanner(System.in);
    static LinkedList<Personne> Liste_Invitee;//liste de toutes les personnes inscritent au gala
    static LinkedList<Reservation> Liste_reservations;//liste de toutes les reservation des gens pour des places au gala
    static Salle salle;
    static int NB_TABLES=3;
	  
    public static void menu_princ()
    {
	System.out.println("=================================================================\n"+
			   "Bienvenue dans l'application de gestion du gala de fin d'annee\n"+
			   "En cas de difficulte pour utiiser ce programme, contactez-nous\n"+
			   "Contact : 06 ...cas ou comiteGala@etu.univ-orleans.fr\n"+
			   "Se munir de sa carte etudiante avant de commencer son inscription\n"+
			   "\n"+
			   "Selectionner :\n"+
			   "0- pour revenir au menu principal\n"+
			   "1- pour s'inscrire/se desincrire\n"+
			   "2- pour reserver/modifier des places de table au diner\n"+
			   "3-pour reserver une place de bus\n"+
			   "4- pour quitter le programme\n"+
			   "===============================================================\n");
	  	  
	int choix = sc.nextInt();
	switch (choix)
	    {
	    case 0: menu_princ();break;
	    case 1: menu_inscription();break;
	    case 2: menu_reserv_table();break;
	    case 3: menu_reserv_bus();break;
	    case 4: quit();break;
	    }
	  	  
    }
	  
    private static void menu_reserv_bus()
    {
	// TODO Auto-generated method stub
	  	  
    }
	  
    private static void menu_reserv_table()
    {
	System.out.println("======================RESERVATION TABLE===========================\n"+
			   "Bienvenue dans l'application de gestion du gala de fin d'annÃ©e\n"+
			   "En cas de difficulte pour utiiser ce programme, contactez-nous\n"+
			   "Contact : 06 ...cas ou comiteGala@etu.univ-orleans.fr\n"+
			   "\n"+
			   "Selectionner :\n"+
			   "0- pour revenir au menu principal\n"+
			   "1- pour reserver une place a une table\n"+
			   "2- pour modifier des places de table au diner\n"+
			   "3- pour voir le plan de table\n"+
			   "4- pour quitter le programme\n"+
			   "===============================================================\n");
	  	  
	int choix = sc.nextInt();
	switch (choix)
	    {
	    case 0: menu_princ();break;
	    case 1: reserv_table();break;
	    case 2: modif_reserv_table();break;
	    case 3: affiche_plan_table();break;
	    case 4: quit();break;
	    }
    }
	  
	  
    private static void affiche_plan_table()
    {
	// TODO Auto-generated method stub
   /*
   a refaire du style 
   ___________________
   Table n° XX
   -------
      Place 1 : Jean MOULIN
      Place 2 : Personne
      Place 3 : Personne
      ....
   ___________________
   */
	if(Liste_reservations.isEmpty())
	    {
		System.out.println("Aucune reservation prise pour le moment !");
	    }
	else
	    {
	  	  	  
		Iterator<Reservation> iter=Liste_reservations.iterator();
		int ligne=0;
		while(iter.hasNext() && sc.next().equals(""))
		    {
	  	  	  	  
			if(ligne <=5)
			    {
	  	  	  	  	  
				System.out.print(iter.next());
				ligne++;
			    }
			else
			    {
	  	  	  	  	  
				System.out.print("\nPas de Reservation\n\n");
				ligne=0;
			    }
	  	  	  
		    }
	    }
    }

    private static void modif_reserv_table()
    {
	// TODO Auto-generated method stub
	  	  
    }

    private static void reserv_table()
    {
	int nb_table=Salle.salle.size();
	for(int i=0;i<NB_TABLES;i++)
	    {
		if (Salle.salle.get(i).isFull())nb_table--;
	    }
	System.out.println("Entrez le Numero de la table que vous avez choisi("+nb_table+" disponibles)");
	int choix_table = sc.nextInt()-1;
	//recherche du nb de place restant sur la table
	  	  
	  	  
	int nb_places_restantes=0;
	int tab_places_restantes[]=new int[8];
	for(int i=0;i<8;i++)
	    {
		if(Salle.salle.get(choix_table).places.get(i).occupant==null)
		    {
			nb_places_restantes++;
			tab_places_restantes[i]=Salle.salle.get(choix_table).places.get(i).numPlace;
		    }
	    }
	//continuer o/n ?

	System.out.println("Il reste "+nb_places_restantes+" places de libre,Continuer avec cette table?(o/n)");
	String rep=sc.next();
	if(rep.equals("o"))
	    {
		//affichage des places restantes
		boolean continu=true;
		int choix_place=0;
		while(continu)
		    {
			System.out.println("Places restante "+affiche_tab(tab_places_restantes));
	  	  	  	  
			System.out.println("Quel est la place que vous souhaitez reservez ?(il y a 8 places/table)");
			//choix de la place selectionne par l'util
			choix_place = sc.nextInt()-1;
			//verif si la place selectionne est deja occupe ou existe
	  	  	  	  
			for(int i=0;i<tab_places_restantes.length;i++)
			    {
				if ( (choix_place==tab_places_restantes[i]) && (choix_place<=8) && (choix_place>=1) )
				    {
					//place libre
					continu=false;
				    }
			    }
	  	  	  	  	  
		    }
		//demande des infos de la personne qui occupera la place a l'util
		String nom_invit="";
		String prenom_invit="";
		boolean trouve=false;
		Reservation reserv = null;
		while(!trouve)
		    {
			System.out.println("Entrez le Nom de la personne dont vous souhaitez reserver la place");
			nom_invit = sc.next();
			System.out.println("Entrez le Prenom de la personne dont vous souhaitez reserver la place");
			prenom_invit = sc.next();
			//recherche de la personne suivant le nom et le prenom car doit etre inscrit avant toutes reservation
			for(int i=0;i<Liste_Invitee.size();i++)
			    {
				if( Liste_Invitee.get(i).Nom.equals(nom_invit.toUpperCase()) && Liste_Invitee.get(i).Prenom.equals(prenom_invit.toUpperCase()) )
				    {
					trouve=true;
					System.out.println(Salle.salle.get(choix_table).places.get(choix_place));
					reserv=new Reservation(Liste_Invitee.get(i),Salle.salle.get(choix_table).places.get(choix_place),Salle.salle.get(choix_table));
				    }
			    }	  
			if(!trouve)System.out.println("Personne non trouvee dans la Liste des gens deja inscrite");
	  	  	  	  
		    }
	  	  	  
	  	  	  
	  	  	  
		DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.getDefault());
		System.out.println("Date de reservation  : "+dateFormat.format(reserv.date_reservation));
		System.out.println("Date de paiement max : "+dateFormat.format(reserv.date_max_paiement));
		//affichage de la date max du paiement
	    }
	else
	    {
		reserv_table();
	    }
    }
	  
	  
	  

    private static String affiche_tab(int[] tab)
    {
	String s="[ ";
	for(int i=0;i<tab.length;i++)
	    {
		s+=tab[i]+" ";
	    }
	s+="]";
	return s;
    }

    /**
     * Partie sur l'inscription et la Desinscription
     */
    //Menu generale sur l'inscription et la Desinscription
    private static void menu_inscription()
    {
	System.out.println("===================INSCRIPTION/DESINSCRIPTION==================\n"+
			   "En cas de difficulte pour utiiser ce programme, contactez-nous\n"+
			   "Contact : 06 ...cas ou comiteGala@etu.univ-orleans.fr\n"+
			   "Se munir de sa carte etudiante avant de commencer son inscription\n"+
			   "\n"+
			   "Selectionner :\n"+
			   "0- pour revenir au menu principal\n"+
			   "1- pour une Inscription\n"+
			   "2- pour une Desinscription\n"+
			   "3- pour quitter le programme\n"+
			   "===============================================================\n");	  
	int choix = sc.nextInt();
	switch (choix)
	    {
	    case 0: menu_princ();break;
	    case 1: smenu_inscription();break;
	    case 2: smenu_desinscription();break;
	    case 3: quit();break;
	    }
	  	  
    }
	  
    //menu sur la Desinscription
    private static void smenu_desinscription()
    {
	System.out.println("=========================DESINSCRIPTION========================\n"+
			   "En cas de difficulte pour utiiser ce programme, contactez-nous\n"+
			   "Contact : 06 ...cas ou comiteGala@etu.univ-orleans.fr\n"+
			   "Se munir de sa carte etudiante avant de commencer son inscription\n"+
			   "\n"+
			   "Selectionner :\n"+
			   "0- pour revenir au menu principal\n"+
			   "1- pour Desinscrire un Etudiant\n"+
			   "2- pour Desinscrire un Invite / Membre de l'universite\n"+
			   "3- pour quitter le programme\n"+
			   "===============================================================\n");	  
	int choix = sc.nextInt();
	switch (choix)
	    {
	    case 0: menu_princ();break;
	    case 1: desinscription_etu();break;
	    case 2: desinscription_invitee();break;
	    case 3: quit();break;
	    }
	  	  	  
    }
	  
    private static void desinscription_invitee()
    {
	System.out.println("Entrez le numero de la personne ?");
	int num_pers=sc.nextInt();
	  	  
	//on recherche avec un iterator de linkedlist<personne> l'invitee correspondant au critere rentre par l'util
	Iterator<Personne> iter=Liste_Invitee.iterator();
	boolean continu=true;
	while (iter.hasNext() && continu)
	    {
		Personne p=iter.next();
		if( p instanceof Invite) //on verifie bien que l'iteration en cour est un invite pour poursuivre
		    {
			Invite i=(Invite)p;
			if ( i.NumPers==num_pers )
			    {
				//si on trouve la personne on demande une confirmation de suppression au cas ou et si oui on fait un remove grace a l'iterateur
				continu=false;
				System.out.println("Confirmer la Suppression de "+i.Nom+" "+i.Prenom+"?(oui/non)");
				String rep=sc.next();
				if(rep.equals("oui"))
				    {
					iter.remove();
					System.out.println("Suppression effectue");
				    }
			    }
		    }
	    }
    }

    private static void desinscription_etu()
    {
	System.out.println("Entrez le numero de la personne ?");
	int num_pers=sc.nextInt();

	//on recherche avec un iterator de linkedlist<personne> l'invitee correspondant au critere rentre par l'util
	Iterator<Personne> iter=Liste_Invitee.iterator();
	boolean continu=true;
	while (iter.hasNext() && continu)
	    {
		Personne p=iter.next();
		if( p instanceof Invite) //on verifie bien que l'iteration en cour est un invite pour poursuivre
		    {
			Invite i=(Invite)p;
			if ( i.NumPers==num_pers )
			    {
				//si on trouve la personne on demande une confirmation de suppression au cas ou et si oui on fait un remove grace a l'iterateur
				continu=false;
				System.out.println("Confirmer la Suppression de "+i.Nom+" "+i.Prenom+"?(oui/non)");
				String rep=sc.next();
				if(rep.equals("oui"))
				    {
					iter.remove();
					System.out.println("Suppression effectue");
				    }
			    }
		    }
	    }
    }

    private static void smenu_inscription()
    {
	  	  
	System.out.println("===========================INSCRIPTION=========================\n"+
			   "En cas de difficulte pour utiiser ce programme, contactez-nous\n"+
			   "Contact : 06 ...cas ou comiteGala@etu.univ-orleans.fr\n"+
			   "Se munir de sa carte etudiante avant de commencer son inscription\n"+
			   "\n"+
			   "Selectionner :\n"+
			   "0- pour revenir au menu principal\n"+
			   "1- pour Inscrire un Etudiant\n"+
			   "2- pour Inscrire un Invite / Membre de l'universite\n"+
			   "3- pour quitter le programme\n"+
			   "===============================================================\n");	  
	int choix = sc.nextInt();
	switch (choix)
	    {
	    case 0: menu_princ();break;
	    case 1: inscription_etu();break;
	    case 2: inscription_invitee();break;
	    case 3: quit();
	    }	  
    }
	  
    private static void inscription_etu()
    {
	//On demande a l'utilisateur de rentre toutes les infos d'un etudiant puis on creee un etudiant qu'on ajoute a a liste de personne du gala
	System.out.println("Entrez le numero etudiant de l'etudiant ?");
	String num_etu=sc.next();
	//verif de l'unicite du num_etudiant avant insertion
	Iterator<Personne> iter=Liste_Invitee.iterator();
	boolean continu=true;
	while (iter.hasNext() && continu)
	    {
		Personne p=iter.next();
		if( p instanceof Etudiant) //on verifie bien que l'iteration en cour est un etudiant pour poursuivre
		    {
			if(num_etu.equals(((Etudiant) p).NumEtu))
			    {
				System.out.println("Numero Etudiant deja enregistre");
				inscription_etu();}
		    }
	    }
	  	  
	System.out.println("Entrez le nom de l'etudiant ?");
	String nom_etu=sc.next();
	System.out.println("Entrez le prenom de l'etudiant ?");
	String prenom_etu=sc.next();
	System.out.println("Entrez le numero de tel de l'etudiant ?");
	String numtel_etu=sc.next();
	System.out.println("Entrez le mail de l'etudiant ?");
	String mail_etu=sc.next();
	System.out.println("Entrez si l'etudiant est diplome?(oui/non)");
	String diplome=sc.next();
	boolean diplo;
	if(diplome.equals("oui"))diplo=true; else diplo=false;
	  	  
	System.out.println("Entrez la promotion de l'etudiant ?");
	//voir liste avec enum des promo
	String Promo=sc.next();
	  	  
	//creation du nouvel etudiant
	Etudiant etu=new Etudiant(num_etu,nom_etu,prenom_etu,numtel_etu,mail_etu,diplo,Promo);
	Liste_Invitee.add(etu);
	System.out.println("Recapitualtif :");
	System.out.println("Numero: "+etu.NumPers+" (Important)"+"\nNom : "+etu.Nom+"\nPrenom: "+etu.Prenom+"\nNumTel :"+etu.NumTel);
	  
    }

    private static void inscription_invitee()
    {
	//idem que pour l'etudiant qauf que la on demande un num etu comme hote car chaque etu n'a droit qu'a 3invitees donc on regarde qu'il respecte cette regle
	//avant d'inserer le nouvel invite
	System.out.println("Entrez le numero de la personne hote ?");
	int num_pers=sc.nextInt();
	System.out.println("Entrez le nom de l'invitee ?");
	String nom_inv=sc.next();
	System.out.println("Entrez le prenom de l'invitee ?");
	String prenom_inv=sc.next();
	System.out.println("Entrez le numero de tel de l'invitee ?");
	String numtel_inv=sc.next();
	System.out.println("Entrez le mail de l'invitee ?");
	String mail_inv=sc.next();

	//verification du nombre d'invitee que l'etu as deja (3 max)
	Iterator<Personne> iter=Liste_Invitee.iterator();
	int cpt=0;
	while (iter.hasNext())
	    {
		Personne p=iter.next();
		if( p instanceof Invite)
		    {
			if( ((Invite)p).num_pers_hote==num_pers){cpt++;}
		    }
	    }
	if(cpt>3)
	    {
		System.out.println("Creation Impossible trop d'invitation deja cree pour cette personne !");	  
	    }
	else
	    {
		//creation du nouvel invitee
		Invite inv=new Invite(num_pers,nom_inv,prenom_inv,numtel_inv,mail_inv);
		Liste_Invitee.add(inv);
		System.out.println("Recapitualtif :");
		System.out.println("Numero: "+inv.NumPers+" (Important)"+"\nNom : "+inv.Nom+"\nPrenom: "+inv.Prenom+"\nNumTel :"+inv.NumTel);
	  
	    }
    }

    private static void quit()
    {
	continu=false;
	//on sauvegarde tout dans les fichiers avant de quitter
	try {
	    sauvegarde();
	} catch (IOException e)
	    {
		e.printStackTrace();
	    }
	System.exit(0);
    }
	  
	  

    private static void sauvegarde()throws IOException
    {
	try{
	    File ff=new File("sauvegarde.txt");
	    // ff.createNewFile();
	    FileWriter ffw=new FileWriter(ff);
	    Iterator<Personne> iter=Liste_Invitee.iterator();
  	  	  
	    ffw.write("$$ NB_TABLES:"+NB_TABLES+"\n\n");
	    ffw.write("\n%% Etudiant :\n");
	    while (iter.hasNext())
		{
		    Personne p=iter.next();
		    if (p instanceof Etudiant)
			{
			   
			    ffw.write(p.NumPers+":"+((Etudiant)p).NumEtu +":"+p.Nom+":"+p.Prenom+":"+p.Mail+":"+p.NumTel+":"+((Etudiant)p).diplome+":"+((Etudiant)p).Promotion+"\n");
			}
		}
	    ffw.write("\n%% Invitee :\n");
	    iter=Liste_Invitee.iterator();
	    while (iter.hasNext())
		{
		    Personne p=iter.next();
		    if( p instanceof Invite)
			{
			    ffw.write(p.NumPers+":"+((Invite)p).num_pers_hote+":"+p.Nom+":"+p.Prenom+":"+p.Mail+":"+p.NumTel+"\n");
			}
		}
	    Iterator<Reservation> iter2=Liste_reservations.iterator();
	    ffw.write("\n%% Reservations :\n");
	    while(iter2.hasNext())
		{
		    Reservation r=iter2.next();
 
			    System.out.println(r.table);
			    System.out.println(r.place.numPlace);
			    System.out.println(r.date_reservation); 
			    System.out.println(r.date_max_paiement);
			    System.out.println(r.NumPers);
			    System.out.println(r.Payee);
			    System.out.println();
		    //NumTable:NumPlace:Datereserv:DateMaxPaiement:NumPers:payee
			    ffw.write(r.table+":"+r.place.numPlace+":"+r.getDateReserv()+":"+r.getDatePaiement()+":"+r.NumPers+":"+r.Payee);
		}
  	  	  	  
	    //	    ffw.write("****** ");  // ecrire une ligne dans le fichier resultat.txt
	    ffw.write("\n"); // forcer le passage a la ligne
	    ffw.close(); // fermer le fichier a la fin des traitements
	}
	catch (Exception e) 
	    {
	    	e.printStackTrace();
	    }
	
    }
    public static void charger_param()throws IOException
    {
	try
	    {	   
		// Si le fichier est valide
		BufferedReader 	buffer = new BufferedReader(new FileReader("sauvegarde.txt"));
		String[] aux;
		for (String ligne = ""; ligne != null; ligne = buffer.readLine())
		    {
			
			if (ligne.startsWith("$$"))
			    {
				aux = ligne.split(":");
				NB_TABLES=Integer.parseInt(aux[1]);
				Personne.NB_PERS=Integer.parseInt(aux[3]);
				Reservation.NB_RESERV=Integer.parseInt(aux[5]);
				salle=new Salle();
			    }
		    }
		
		buffer.close();	
	    }
	catch (Exception e) 
	    {
		e.printStackTrace();
	    }

    }
    
    
    public static void charger() throws IOException
    {
	// Li le fichier ligne par ligne et complete le tableau de station
	/*
	 $$ NB_TABLES:8:NB_PERS:3:NB_RESERV:3


	 %% Etudiant :
	 %%NumPers:Numetu:Prenom:Nom:Mail:NumTel:Diplomee:Promo
	 1:2101322:JEAN:BON:SUPERTOMATE@YOPMAIL.FR:0238450118:true:STAPS
	 
	 %% Invitee :
	 %%NumPers:NumPersHote:Prenom:Nom:Mail:NumTel
	 2:1:JEANINE:BON:A PAS:0677536273
	 3:1:ROBERT:BON:CACA@LYCOS.FR:666
	 
	 %% Reservations :
	 %%NumReserv:NumTable:NumPlace:Datereserv:DateMaxPaiement:NumPers:payee
	 1:2:8:10/12/13:20/12/13:3:false
	 2:2:7:10/12/13:20/12/13:1:false
	 3:2:6:10/12/13:20/12/13:2:false	  	  	   
	 
	*/
	boolean reserv = false;
	boolean etu = false;
	boolean invitee =false;

	try
	    {
		// Si le fichier est valide
		BufferedReader buffer = new BufferedReader(new FileReader("sauvegarde.txt"));
		String[] aux;
		for (String ligne = ""; ligne != null; ligne = buffer.readLine())
		    {  	  
			// Si la ligne est vide ou est un commentaire
			if (ligne.startsWith("%%") || ligne.equals(""))
			    {
				
				if (ligne.equals("%% Reservations :"))
				    {
					reserv = true;
					etu = false;
					invitee = false;
				
				    }
				else if (ligne.equals("%% Etudiant :"))
				    {
					reserv = false;
					etu = true;
					invitee = false;
				    }
				else if (ligne.equals("%% Invitee :"))
				    {
					reserv = false;
					etu = false;
					invitee = true;
				    }
			    }
			else
			    {
				// On enleve les ":" de la ligne recupere dans le buffer
				aux = ligne.split(":");
				// Si on est dans la partie reservation
				if (reserv)
				    {
					//%%NumReserv:NumTable:NumPlace:Datereserv:DateMaxPaiement:NumPers:payee
					System.out.println("NumReservation: "+aux[0]);
					System.out.println("NumTable: "+aux[1]);
					System.out.println("NumPlace: "+aux[2]);
					System.out.println("Datereserv: "+aux[3]);
					System.out.println("DatemaxPaiement: "+aux[4]);
					System.out.println("NumPers: "+aux[5]);
					System.out.println("Payee: "+aux[6]);
					System.out.println("--------------------------");

					Reservation r= new Reservation(Integer.parseInt(aux[0]) ,Integer.parseInt(aux[1]) ,Integer.parseInt(aux[2]),aux[3],aux[4],Integer.parseInt(aux[5]),Boolean.parseBoolean(aux[6]));
					Liste_reservations.add(r);	  
				    }
				else if (etu) // Si on est dans la partie Etudiant
				    {
					System.out.println("NumPers: "+aux[0]);
					System.out.println("NumEtu: "+aux[1]);
					System.out.println("Prenom: "+aux[2]);
					System.out.println("Nom: "+aux[3]);
					System.out.println("Mail: "+aux[4]);
					System.out.println("Numtel: "+aux[5]);
					System.out.println("Diplo?: "+aux[6]);
					System.out.println("Promo: "+aux[7]);
					System.out.println("--------------------------");
					Etudiant e=new Etudiant (Integer.parseInt(aux[0]),aux[1],aux[2],aux[3],aux[4],aux[5],Boolean.parseBoolean(aux[6]),aux[7]);
					Liste_Invitee.add(e);
				    }
				else if (invitee) //Si on est dans la partie Invitee
				    {
					//NumPers:NumPersHote:Prenom:Nom:Mail:NumTel	  
						
					System.out.println("NumPers: "+aux[0]);
					System.out.println("NumPersHote: "+aux[1]);
					System.out.println("Prenom: "+aux[2]);
					System.out.println("Nom: "+aux[3]);
					System.out.println("Mail: "+aux[4]);
					System.out.println("NumTel: "+aux[5]);
					System.out.println("--------------------------");

					Invite i=new Invite (Integer.parseInt(aux[0]),Integer.parseInt(aux[1]),aux[2],aux[3],aux[4],aux[5]);
					Liste_Invitee.add(i);
					
				    }
			    }
	  	  	  	  
		    }
		buffer.close();
	    }
	catch (Exception e) 
	    {
		e.printStackTrace();
	    }
    }	  
    
    
    
    
    
    public static void main(String[] args)
    {
	  	  
	  	  

	while (continu )
	    {
		//jeu d'essai
		/*	Etudiant neu=new Etudiant("666","BON", "Jean","0677536273", "supertomate@yopmail.fr",true,"STAPS");
			Liste_Invitee.add(neu);
			Invite inv=new Invite(666,"Bon","Roseline","18","a pas");
			Liste_Invitee.add(inv);
			Invite inv2=new Invite(666,"Bon","Jacques","17","a pas 2");
			Liste_Invitee.add(inv2);
			Reservation res= new Reservation (2;7;10/12/13;20/12/13;3;false);
			Liste_Reservation.add(res);
			

		*/
		Liste_Invitee=new LinkedList<Personne>();
		Liste_reservations=new LinkedList<Reservation>();

		try 
		    {
			charger_param();
			charger();	
		    } 
		catch (IOException e)
		    {
			e.printStackTrace();
		    }
		menu_princ();
	    }
	
    }	  
}